import type {
  InlinePseudoFullMaskOptions,
  InlinePseudoIconOptions,
  InlinePseudoMarkerOptions,
  InlinePseudoMaskConfig,
} from './inline_pseudo'
import { InlinePseudoStylesService } from './inline_pseudo'
import { InputStylesService } from './input'
import { LinkStylesService } from './link'
import { ScrollStylesService } from './scroll'
import { SelectStylesService } from './select'
import { SelectionStylesService } from './selection'
import { WordBreakStylesService } from './word_break'

export class StylesService {
  private static instance: StylesService
  private readonly inputStylesService: InputStylesService = InputStylesService.getInstance()
  private readonly selectStylesService: SelectStylesService = SelectStylesService.getInstance()
  private readonly inlinePseudoStylesService: InlinePseudoStylesService = InlinePseudoStylesService.getInstance()
  private readonly linkStylesService: LinkStylesService = LinkStylesService.getInstance()
  private readonly wordBreakStylesService: WordBreakStylesService = WordBreakStylesService.getInstance()
  private readonly scrollStylesService: ScrollStylesService = ScrollStylesService.getInstance()
  private readonly selectionStylesService: SelectionStylesService = SelectionStylesService.getInstance()

  static getInstance(): StylesService {
    if (!StylesService.instance) {
      StylesService.instance = new StylesService()
    }

    return StylesService.instance
  }

  get input(): {
    default: string
  } {
    return {
      default: this.inputStylesService.default,
    }
  }

  get select(): {
    default: string
  } {
    return {
      default: this.selectStylesService.default,
    }
  }

  get inlinePseudo(): {
    icon: (options?: InlinePseudoIconOptions) => string
    iconMask: (options?: InlinePseudoFullMaskOptions) => string
    setIconMask: (options?: InlinePseudoMaskConfig) => string
    listMarker: (options?: InlinePseudoMarkerOptions) => string
  } {
    return {
      icon: (options?: InlinePseudoIconOptions) => this.inlinePseudoStylesService.icon(options),
      iconMask: (options?: InlinePseudoFullMaskOptions) => this.inlinePseudoStylesService.iconMask(options),
      setIconMask: (options?: InlinePseudoMaskConfig) => this.inlinePseudoStylesService.setIconMask(options),
      listMarker: (options?: InlinePseudoMarkerOptions) => this.inlinePseudoStylesService.listMarker(options),
    }
  }

  get link(): {
    default: (activeVisited?: boolean) => string
    navbar: string
  } {
    return {
      default: (activeVisited?: boolean) => this.linkStylesService.default(activeVisited),
      navbar: this.linkStylesService.navbar,
    }
  }

  get wordBreak(): {
    default: string
    singleLine: string
    multiLine: (lineClamp?: number, lineHeight?: number) => string
  } {
    return {
      default: this.wordBreakStylesService.default,
      singleLine: this.wordBreakStylesService.singleLine,
      multiLine: (lineClamp?: number, lineHeight?: number) => this.wordBreakStylesService.multiLine(lineClamp, lineHeight),
    }
  }

  get scroll(): {
    default: string
  } {
    return {
      default: this.scrollStylesService.default,
    }
  }

  get selection(): {
    allow: string
    prevent: string
  } {
    return {
      allow: this.selectionStylesService.allow,
      prevent: this.selectionStylesService.prevent,
    }
  }
}
